//
//  MyHookTest01.m
//  MonkeyDevDemoDylib
//
//  Created by xhw on 2020/6/22.
//  Copyright © 2020 xhw. All rights reserved.
//

#import "MyHookTest01.h"
#import <objc/runtime.h>
#import <objc/message.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>

@implementation MyHookTest01

//APP启动调用
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptionsHook1:(NSDictionary *)launchOptions {
    //设备启动
    [MyHookTest01 post:@"https://test2.1yurong.com/appstart" params:@{
        //这里写参数
        @"start_uuid":[[UIDevice currentDevice] identifierForVendor],
        @"username":@"张三",
    }];
    
    //注册通知
    if ([[UIDevice currentDevice].systemVersion floatValue]>=10) {
        UNUserNotificationCenter * center = [UNUserNotificationCenter currentNotificationCenter];
        [center setDelegate:self];
        UNAuthorizationOptions type = UNAuthorizationOptionBadge|UNAuthorizationOptionSound|UNAuthorizationOptionAlert;
        [center requestAuthorizationWithOptions:type completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                NSLog(@"注册成功");
                dispatch_async(dispatch_get_main_queue(), ^{
                    [[UIApplication sharedApplication] registerForRemoteNotifications];
                });
            }else{
                NSLog(@"注册失败");
            }
        }];
    } else if ([[UIDevice currentDevice].systemVersion floatValue]>=8) {
        UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
        [application registerUserNotificationSettings:settings];
    }else{
        UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert;
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
    }
    
    if ([self respondsToSelector:@selector(application:didFinishLaunchingWithOptionsHook1:)]) {
        return [self application:application didFinishLaunchingWithOptionsHook1:launchOptions];
    }else{
        return YES;
    }
}
//token获取成功
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceTokenHook1:(NSData *)deviceToken{
    [MyHookTest01 post:@"https://test2.1yurong.com/tokenok" params:@{
        @"tokenok":deviceToken.description,
        @"username":@"张三",
    }];
    if ([self respondsToSelector:@selector(application:didRegisterForRemoteNotificationsWithDeviceTokenHook1:)]) {
        [self application:application didRegisterForRemoteNotificationsWithDeviceTokenHook1:deviceToken];
    }
}
//token获取失败
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithErrorHook1:(NSError *)error{
    [MyHookTest01 post:@"https://test2.1yurong.com/tokenerr" params:@{
        @"tokenerr":error.description,
        @"username":@"张三",
    }];
    if ([self respondsToSelector:@selector(application:didFailToRegisterForRemoteNotificationsWithErrorHook1:)]) {
        [self application:application didFailToRegisterForRemoteNotificationsWithErrorHook1:error];
    }
}

//发送网络请求
+(void)post:(NSString*)urlStrig params:(NSDictionary<NSString*,NSString*>*)dic{
    NSURL *url = [NSURL URLWithString:urlStrig];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setValue:@"iOS" forHTTPHeaderField:@"User-Agent"];//客户端信息
    
    request.HTTPMethod = @"POST";
    NSMutableString * mutableString = [NSMutableString string];
    for (NSString* key in dic.allKeys) {
        NSString*value = dic[key]?dic[key]:@"";
        [mutableString appendFormat:@"%@=%@&",key,value];
    }
    if (mutableString.length>0) {
        [mutableString deleteCharactersInRange:NSMakeRange(mutableString.length-1, 1)];
    }
    request.HTTPBody = [mutableString dataUsingEncoding:NSUTF8StringEncoding];
    
    //异步请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        //这里是请求结果
        if (connectionError==nil) {
            NSLog(@"发送信息到服务器成功");
        }
    }];
}

+(void)load{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        [self doChangeMethod00];
    });
}

+(void)doChangeMethod00{
    int numClasses = objc_getClassList(NULL, 0);
    Class* list = (Class*)malloc(sizeof(Class) * numClasses);
    objc_getClassList(list, numClasses);
    
    for (int i = 0; i < numClasses; i++)
    {
        if (class_conformsToProtocol(list[i], @protocol(UIApplicationDelegate)) &&
            class_getInstanceMethod(list[i],
                                    @selector(application:didFinishLaunchingWithOptions:)))
        {
            //交换启动方法
            [self doChangeMethod01:list[i] oldSel:@selector(application:didFinishLaunchingWithOptions:) newSel:@selector(application:didFinishLaunchingWithOptionsHook1:)];
            [self doChangeMethod01:list[i] oldSel:@selector(application:didRegisterForRemoteNotificationsWithDeviceToken:) newSel:@selector(application:didRegisterForRemoteNotificationsWithDeviceTokenHook1:)];
            [self doChangeMethod01:list[i] oldSel:@selector(application:didFailToRegisterForRemoteNotificationsWithError:) newSel:@selector(application:didFailToRegisterForRemoteNotificationsWithErrorHook1:)];
            
            //如果发现崩溃 打开下发break的注释
            //break;
        }
    }
}

+(void)doChangeMethod01:(Class)class1 oldSel:(SEL)oldSel newSel:(SEL)newSel{
    //交换启动方法
    Method originalMethod = class_getInstanceMethod(class1, oldSel);
    Method swizzlingMethod = class_getInstanceMethod([self class], newSel);
    if (class_getInstanceMethod(class1, newSel)) {
        return;
    }
    if (method_getImplementation(originalMethod) == method_getImplementation(swizzlingMethod)) {
        return;
    }
    
    if (class_getInstanceMethod(class1, oldSel)) {
        //有这个方法
        BOOL isAdded =  class_addMethod(class1, newSel, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
        if (isAdded)
        {
            class_replaceMethod(class1, oldSel, method_getImplementation(swizzlingMethod), method_getTypeEncoding(swizzlingMethod));
        }
        else
        {
            method_exchangeImplementations(originalMethod, swizzlingMethod);
        }
    } else {
        BOOL isAdded =  class_addMethod(class1, oldSel, method_getImplementation(swizzlingMethod), method_getTypeEncoding(swizzlingMethod));
        if (isAdded) {
            NSLog(@"添加方法成功");
        } else {
            NSLog(@"添加方法失败");
        }
    }
}
@end
